package com.hzlj.position.locate.rest;

import cn.hutool.core.util.ObjectUtil;
import com.fz.common.base.core.BeanUtils;
import com.fz.common.base.core.RequestUtil;
import com.fz.common.base.exception.PubException;
import com.fz.common.dict.dto.DictionaryMenuDTO;
import com.fz.common.dict.service.DictionaryService;
import com.hzlj.common.message.common.dto.audioConvert.AudioConvertRequestDTO;
import com.hzlj.common.message.common.dto.audioConvert.AudioConvertResultDTO;
import com.hzlj.common.message.common.dto.voiceprint.VoiceprintMatchDTO;
import com.hzlj.common.message.common.dto.voiceprint.VoiceprintMatchResultDTO;
import com.hzlj.common.message.common.dto.voiceprint.VoiceprintUserDTO;
import com.hzlj.common.message.common.util.AudioConvertRestUtil;
import com.hzlj.common.message.common.util.VoiceprintRestUtil;
import com.hzlj.position.config.config.PositionConfig;
import com.hzlj.position.locate.common.dto.reportAudio.ReportAudioExtDTO;
import com.hzlj.position.locate.common.enums.ReportAudioStatus;
import com.hzlj.position.locate.common.enums.VoiceprintMatch;
import com.hzlj.sqjz.config.common.dto.file.FileQueryResultDTO;
import com.hzlj.sqjz.config.service.FileService;
import com.hzlj.sqjz.jz.common.dto.common.JzCommonQueryResultDTO;
import com.hzlj.sqjz.jz.service.JzJbxxService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AudioRest {

    private final static String REPORT_AUDIO_ABN_WORD = "REPORT_AUDIO_ABN_WORD";
    @Resource
    private DictionaryService dictionaryService;
    @Resource
    private JzJbxxService jzJbxxService;
    @Resource
    private FileService fileService;
    @Resource
    private PositionConfig positionConfig;

    @Data
    public static class ConvertResult {
        /**
         * 上报状态,dict-REPORT_AUDIO_STATUS
         */
        private String reportStatus;
        /**
         * 语音转换内容
         */
        private String audioText;
        /**
         * 声纹核验状态,dict-REPORT_AUDIO_VOICE_PRINT_MATCH
         */
        private String voiceprintMatch;
        /**
         * 其他信息
         */
        ReportAudioExtDTO ext = new ReportAudioExtDTO();
    }

    public ConvertResult convert(String serviceId,
                                 String jzId,
                                 String fileId) {
        //获取文件
        FileQueryResultDTO file = fileService.getFileById(fileId);
        if (file == null) {
            throw new PubException("没有找到音频文件，请确认上传成功!");
        }
        String fileUrl = positionConfig.getAudio().getUseAudioNetUrl() ? file.getFullNetUrl() : file.getFullUrl();
        //基本信息
        JzCommonQueryResultDTO jzJbxx = jzJbxxService.getJzCommonById(jzId);
        ConvertResult convertResult = new ConvertResult();
        try {
            //文字转换
            this.convertAudioText(serviceId, jzJbxx, fileUrl, convertResult);
        } catch (Exception e) {
            log.error("音频转文字出错:serviceId={},jzId={},fileId={}", serviceId, jzJbxx, fileUrl, e);
        }
        try {
            //声纹识别
            this.convertVoiceprint(serviceId, jzJbxx, fileUrl, convertResult);
        } catch (Exception e) {
            log.error("音频声纹识别出错:serviceId={},jzId={},fileId={}", serviceId, jzJbxx, fileUrl, e);
        }

        return convertResult;
    }

    /**
     * 文字转换
     */
    private void convertAudioText(String serviceId,
                                  JzCommonQueryResultDTO jzJbxx,
                                  String fileUrl,
                                  ConvertResult result) {
        ReportAudioExtDTO ext = result.getExt();

        //文字转换
        AudioConvertResultDTO text = AudioConvertRestUtil.convert(new AudioConvertRequestDTO()
                .setServiceId(serviceId)
                .setOrgCode(jzJbxx.getJgCode())
                .setUrl(fileUrl)
        );
        //设置文字内容
        result.setAudioText(text.getLatticeJoin());
        if (ObjectUtil.isNotEmpty(text.getLattices())) {
            ext.setAudioTexts(text.lattices());
        }

        //上报状态是否正常(是否包含异常关键词)
        if (ObjectUtil.isNotEmpty(result.getAudioText())) {
            List<DictionaryMenuDTO> words = this.dictionaryService.getByType(RequestUtil.getAppId(), REPORT_AUDIO_ABN_WORD);
            if (ObjectUtil.isNotEmpty(words)) {
                ext.setAbnWords(
                        words.stream().map(DictionaryMenuDTO::getName).filter(e -> result.getAudioText().contains(e)).collect(Collectors.toList())
                );
            }
        }
        //异常状态
        result.setReportStatus(ObjectUtil.isEmpty(ext.getAbnWords()) ?
                ReportAudioStatus.NORMAL.getStatus() : ReportAudioStatus.ABN.getStatus());

        //设置ext
        result.setExt(BeanUtils.isEmpty(ext) ? null : ext);
    }

    /**
     * 声纹识别
     */
    private void convertVoiceprint(String serviceId,
                                   JzCommonQueryResultDTO jzJbxx,
                                   String fileUrl,
                                   ConvertResult result) {
        //声纹识别
        VoiceprintMatchResultDTO matchResult = VoiceprintRestUtil.match(new VoiceprintMatchDTO()
                .setServiceId(serviceId)
                .setFileUrl(fileUrl)
                .setUser(VoiceprintUserDTO.of(jzJbxx.getJzId(), jzJbxx.getXm(), jzJbxx.getJgCode(), jzJbxx.getJgMc()))
        );
        result.setVoiceprintMatch(matchResult.isMatch() ?
                VoiceprintMatch.SELF.getMatch() : VoiceprintMatch.OTHER.getMatch()
        );

        //设置提示内容
        ReportAudioExtDTO ext = result.getExt();
        if (ext == null) {
            ext = new ReportAudioExtDTO();
        }
        ext.setVoiceprintMatchMsg(matchResult.getStatusMsg());
        ext.setVoiceprintMatchScore(matchResult.getScore());
        //设置ext
        result.setExt(ext);
    }
}
